﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using CloudShot.Core.Types;
using CloudShot.Utils;

namespace CloudShot.Services
{
	internal class RecentShotsQueue : IEnumerable<ShotInfo>
	{
		private const int QUEUE_SIZE = 10;
		private readonly Queue<ShotInfo> _shots = new Queue<ShotInfo>(QUEUE_SIZE);

		public int Count { get { return _shots.Count; } }

		public void Add(ShotInfo shot)
		{
			if (_shots.Count >= QUEUE_SIZE)
			{
				int count = _shots.Count - (QUEUE_SIZE - 1);
				for (int i = 0; i < count; i++)
				{
					ShotInfo s = _shots.Dequeue();
					RemoveThumbnail(s);
				}
			}

			_shots.Enqueue(shot);
			SaveThumbnail(shot);
		}

		public void Load(IEnumerable<ShotInfo> shots)
		{
			int count = 0;
			foreach (ShotInfo shot in shots)
			{
				_shots.Enqueue(shot);
				InitThumbnail(shot);

				count++;
				if (count == QUEUE_SIZE)
					return;
			}
		}

		private void InitThumbnail(ShotInfo shot)
		{
			string path = Path.Combine(AppHelper.ThumbnailsPath, shot.Name);

			if (File.Exists(path))
				shot.SetThumbnail(Image.FromFile(path));
		}

		private void SaveThumbnail(ShotInfo shot)
		{
			if (!Directory.Exists(AppHelper.ThumbnailsPath))
				Directory.CreateDirectory(AppHelper.ThumbnailsPath);//create directory if not exist

			string pathToSave = Path.Combine(AppHelper.ThumbnailsPath, shot.Name);

			using (var ms = new MemoryStream())
			using (var fs = new FileStream(pathToSave, FileMode.Create))
			{
				shot.Thumbnail.Save(ms, ImageFormat.Png);
				ms.WriteTo(fs);
			}
		}

		private void RemoveThumbnail(ShotInfo shot)
		{
			if (shot.Thumbnail != null)
				shot.Thumbnail.Dispose();//withiout this will be exception 'The process cannot access the file'

			try
			{
				File.Delete(Path.Combine(AppHelper.ThumbnailsPath, shot.Name));
			}
			catch (Exception)
			{
				//if file cannot be deleted, because used by another process
			}
		}

		public IEnumerator<ShotInfo> GetEnumerator()
		{
			return _shots.GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}
	}
}